{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# GPyOpt: using context variables\n",
    "\n",
    "### Javier Gonzalez and Rodolphe Jenatton, Amazon.com\n",
    "\n",
    "\n",
    "*Last updated Monday, July 2017*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this notebook we are going to see how to used GPyOpt to solve optimizaiton problems in which certain varaibles are fixed during the optimization phase. These are called context variables. For details see:\n",
    "\n",
    "\n",
    "*Krause, A. & Ong, C. S. Contextual gaussian process bandit optimization Advances in Neural Information Processing Systems (NIPS), 2011, 2447-2455*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%pylab inline\n",
    "import GPyOpt\n",
    "from numpy.random import seed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "func  = GPyOpt.objective_examples.experimentsNd.alpine1(input_dim=5) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we define the domain of the function to optimize as usual."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "mixed_domain =[{'name': 'var1', 'type': 'continuous', 'domain': (-5,5),'dimensionality': 3},\n",
    "               {'name': 'var2', 'type': 'discrete', 'domain': (3,8,10)},\n",
    "               {'name': 'var3', 'type': 'categorical', 'domain': (0,1,2)},\n",
    "               {'name': 'var4', 'type': 'continuous', 'domain': (-1,2)}]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "myBopt = GPyOpt.methods.BayesianOptimization(f=func.f,                     # Objective function       \n",
    "                                             domain=mixed_domain,          # Box-constraints of the problem\n",
    "                                             initial_design_numdata = 5,   # Number data initial design\n",
    "                                             acquisition_type='EI',        # Expected Improvement\n",
    "                                             exact_feval = True,\n",
    "                                             evaluator_type = 'local_penalization',\n",
    "                                             batch_size = 5\n",
    "                                             )           # True evaluations, no sample noise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we run the optimization for 20 iterations or a maximum of 60 seconds and we show the convergence plots."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "max_iter = 2    ## maximum number of iterations\n",
    "max_time = 60   ## maximum allowed time\n",
    "eps      = 0    ## tolerance, max distance between consicutive evaluations."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To set a context, we just need to create a dicctionary with the variables to fix and pass it to the Bayesian ottimization object when running the optimization. Note that, everytime we run new iterations we can set other variables to be the context. Note that for variables in which the dimaensionality has been specified in the domain, a subindex is internally asigned. For instance if the variables is called 'var1' and has dimensionality 3, the first three positions in the internal representation of the domain will be occupied by variables 'var1_1', 'var1_2' and 'var1_3'. If no dimensionality is added, the internal naming remains the same. For instance, in the example above 'var3' should be fixed its original name. See below for details."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "myBopt.run_optimization(max_iter,eps=eps)\n",
    "myBopt.run_optimization(max_iter,eps=eps,context = {'var1_1':.3, 'var1_2':0.4})\n",
    "myBopt.run_optimization(max_iter,eps=eps,context = {'var1_1':0, 'var3':2})\n",
    "myBopt.run_optimization(max_iter,eps=eps,context = {'var1_1':0, 'var2':3},)\n",
    "myBopt.run_optimization(max_iter,eps=eps,context = {'var1_1':0.3, 'var3':1, 'var4':-.4})\n",
    "myBopt.run_optimization(max_iter,eps=eps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can now visualize the results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "np.round(myBopt.X,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
